package main

import (
	"bufio"
	"gitee.com/jmdvirus/jkgo/jk/jklog"
	"github.com/atotto/clipboard"
	"io"
	"net"
	"strconv"
	"strings"
	"time"
)

type RecvClipboard struct {
	conn net.Conn
	data string
}

func NewRecvClipboard(addr string, port int) (*RecvClipboard, error) {
	rc := &RecvClipboard{}
	fulladdr := addr + ":" + strconv.Itoa(port)
	jklog.L().Infoln("connect to ", fulladdr)
	x, err := net.ResolveTCPAddr("tcp", fulladdr)
	if err != nil {
		return nil, err
	}
	rc.conn, err = net.DialTCP("tcp", nil, x)
	if err != nil {
		return nil, err
	}
	rc.data, _ = clipboard.ReadAll()
	return rc, nil
}

func (rc *RecvClipboard) SendData(data string) error {
	n, err := rc.conn.Write([]byte(data))
	if err != nil {
		return err
	}
	jklog.L().Infoln("write len ", n)
	return nil
}

func (rc *RecvClipboard) CheckClipboard() {
	for {
		dd, err1 := clipboard.ReadAll()
		if err1 != nil {
			jklog.L().Warnln("read clipboard error ", err1)
		} else {
			if dd != rc.data && len(dd) > 0 {
				jklog.L().Debugln("get new clipboard data len = ", len(dd))
				sdata := "clip" + "|" + strconv.Itoa(len(dd)) + "|" + dd
				rc.SendData(sdata)
				rc.data = dd
			}
		}
		time.Sleep(time.Second * 1)
	}
}

func (rc *RecvClipboard) RecvCycle() error {
	bufreader := bufio.NewReader(rc.conn)
	buf := make([]byte, 2<<20)
	jklog.L().Infoln("start to recv block")
	for {
		cmd, err := bufreader.ReadString('|')
		if err != nil {
			if io.EOF == err {
				jklog.L().Infoln("closed")
				return err
			}
			jklog.L().Errorln("read fail")
			time.Sleep(time.Second * 5)
			continue
		}
		jklog.L().Infoln("read cmd = ", cmd)
		cmd = strings.TrimRight(cmd, "|")
		if cmd == "startSend" {
			n, _ := bufreader.ReadString('|')
			n = strings.TrimRight(n, "|")
			datalen, err := strconv.Atoi(n)
			if err != nil {
				jklog.L().Errorln("error length ", n)
				continue
			}
			maxLen := datalen
			curLen := 0
			var bufall []byte
			for {
				n, err := bufreader.Read(buf)
				if err != nil {
					jklog.L().Errorln(err)
					break
				}
				bufall = append(bufall, buf[:n]...)
				curLen += n
				if curLen >= maxLen {
					jklog.L().Infoln("read done of length ", curLen)
					break
				}
			}

			jklog.L().Infoln("bufall len = ", len(bufall))
			err = clipboard.WriteAll(string(bufall))
			if err != nil {
				jklog.L().Errorln("write to clip board fail ", err)
			} else {
				rc.data = string(bufall)
			}
		}
	}
	return nil
}
